<div id="divOptions">
<table>
<tr>
<td>Width:</td>
<td><input type="text" id="txtWidth" value="101" /></td>
<td>Wall Color:</td>
<td><input type="text" id="txtWallColor" value="#888888" /></td>
<td>Solution Color:</td>
<td><input type="text" id="txtSolutionColor" value="green" /></td>
</tr>
<tr>
<td>Height:</td>
<td><input type="text" id="txtHeight" value="147" /></td>
<td>Passage Color:</td>
<td><input type="text" id="txtPassageColor" value="white" /></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Delay:</td>
<td><input type="text" id="txtDelay" value="1" /></td>
<td>Status:</td>
<td><input type="text" id="txtStatus" value="Not started" readonly="readonly" /></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td colspan="6" style="text-align:right">
<input type="button" onclick="javascript:document.getElementById('divOptions').style.display='none'" value="Hide Options" />
<input type="button" onclick="javascript:toggleEntrance()" value="Entrance" style="padding-left:40px;padding-right:40px" />
<input type="button" onclick="javascript:solve()" value="Solve" style="padding-left:40px;padding-right:40px" />
<input type="button" onclick="javascript:drawMaze()" value="Draw" style="padding-left:40px;padding-right:40px" />
</td>
</tr>
</table>
</div>
<canvas id="myCanvas" width="10" height="10" onclick="javascript:ToggleOptions()">
You browser does not support Canvas.
</canvas>
<script type="text/javascript"> 

mazeWidth = null
mazeHeight = null
canvas = null
context = null
map = null
myStack = null
startPoint = null
currentPoint = null
wayFound = null
previousPoint = null
directions = null
direction = null
delay = null
solution = null

function solve()
{
	solveStyle = 'a'
        context.fillStyle = document.getElementById('txtSolutionColor').value
        previousPoint = new Point(1, 1)
        for (i = 0; i < solution.length; i++)
        {
			if ( solveStyle == 'compact' )
			{
                context.fillRect(solution[i].x*10+4, solution[i].y*10+4, 2, 2)
                context.fillRect(
                        (solution[i].x+previousPoint.x)*5+4,
                        (solution[i].y+previousPoint.y)*5+4,
                        2, 2)
			} else {
                context.fillRect(solution[i].x*10, solution[i].y*10, 10, 10)
                context.fillRect(
                        (solution[i].x+previousPoint.x)*5,
                        (solution[i].y+previousPoint.y)*5,
                        10, 10)
			}
                previousPoint = new Point(solution[i].x, solution[i].y)
        }
		if ( solveStyle == 'compact' )
			{
	context.fillRect(15, 5, 2, 2)
	context.fillRect(mazeWidth * 10 - 15, mazeHeight * 10 - 5, 2, 2)
			} else {
	context.fillRect(10, 0, 10, 10)
	context.fillRect(mazeWidth * 10 - 20, mazeHeight * 10 - 10, 10, 10)
			}
}

function HasAnyFreeDirections(point)
{
        if ( point.y > 1 )
                if ( map[point.y-2][point.x  ] == 'wall' ) return true
        if ( point.x < mazeWidth - 3 )
                if ( map[point.y  ][point.x+2] == 'wall' ) return true
        if ( point.y < mazeHeight - 3 )
                if ( map[point.y+2][point.x  ] == 'wall' ) return true
        if ( point.x > 1 )
                if ( map[point.y  ][point.x-2] == 'wall' ) return true
        return false
}
function Point(x, y)
{
        this.x = x
        this.y = y
}
function PointIsUsed(x, y, exceptX, exceptY)
{
        if (x<0 || y<0 || x>mazeWidth-1 || y>mazeHeight-1) return true
        if (map[y][x] == 'passage') return true
        return false
}

function drawSection()
{
        wayFound = true
        drawPoint()
        currentPoint = myStack.pop()
        if (!(solution[solution.length-1].x==mazeWidth-2 && 
                solution[solution.length-1].y==mazeHeight-2))
        {
                while (!(solution[solution.length-1].x==currentPoint.x && 
                        solution[solution.length-1].y==currentPoint.y))
                {
                        solution.pop()
                }
        }
        while (myStack.length > 0 && !HasAnyFreeDirections(currentPoint))
        {
                currentPoint = myStack.pop()
                if (!(solution[solution.length-1].x==mazeWidth-2 && 
                        solution[solution.length-1].y==mazeHeight-2))
                {
                        while (!(solution[solution.length-1].x==currentPoint.x && 
                                solution[solution.length-1].y==currentPoint.y))
                        {
                                solution.pop()
                        }
                }
        }
}

function drawPoint()
{
        wayFound = false
        previousPoint = new Point(currentPoint.x, currentPoint.y)

        directions = new Array(4)
        for (i = 0; i < 4; i++)
        {
                direction = Math.floor(Math.random() * 4)
                while (directions.indexOf(direction) != -1)
                        direction = Math.floor(Math.random() * 4)
                directions[i] = direction
        }
        
        for (i = 0; i < 4; i++)
        {
                if (directions[i]==0 && !wayFound && !PointIsUsed(currentPoint.x  , currentPoint.y-2, currentPoint.x, currentPoint.y))
                {
                        currentPoint.y = currentPoint.y - 2
                        wayFound = true
                }
                if (directions[i]==1 && !wayFound && !PointIsUsed(currentPoint.x+2, currentPoint.y  , currentPoint.x, currentPoint.y))
                {
                        currentPoint.x = currentPoint.x + 2
                        wayFound = true
                }
                if (directions[i]==2 && !wayFound && !PointIsUsed(currentPoint.x  , currentPoint.y+2, currentPoint.x, currentPoint.y))
                {
                        currentPoint.y = currentPoint.y + 2
                        wayFound = true
                }
                if (directions[i]==3 && !wayFound && !PointIsUsed(currentPoint.x-2, currentPoint.y  , currentPoint.x, currentPoint.y))
                {
                        currentPoint.x = currentPoint.x - 2
                        wayFound = true
                }
        }
        if ((solution.length == 0) ||
                (!(solution[solution.length-1].x==mazeWidth-2 && 
                solution[solution.length-1].y==mazeHeight-2)))
                solution.push(new Point(currentPoint.x, currentPoint.y))
        if (wayFound) {
                context.fillRect(10*currentPoint.x, 10*currentPoint.y, 10, 10)
                myStack.push(new Point(currentPoint.x, currentPoint.y))
                context.fillRect(5*(currentPoint.x+previousPoint.x), 5*(currentPoint.y+previousPoint.y), 10, 10)
                map[currentPoint.y][currentPoint.x] = 'passage'
                setTimeout('drawPoint()', delay)
        }
        else if (myStack.length > 0) setTimeout('drawSection()', delay)
        else document.getElementById('txtStatus').value = 'Finished'
}

function drawMaze()
{
        document.getElementById('txtStatus').value = 'Started'
        mazeWidth = document.getElementById('txtWidth').value
        mazeHeight = document.getElementById('txtHeight').value
        document.getElementById('myCanvas').width = 
                mazeWidth * 10
        document.getElementById('myCanvas').height = 
                mazeHeight * 10
        delay = document.getElementById('txtDelay').value

        canvas = document.getElementById('myCanvas')
        context = canvas.getContext('2d')
        map = new Array(61)
        myStack = new Array()
        solution = new Array()
        context.fillStyle = document.getElementById('txtWallColor').value
        context.fillRect(0, 0, mazeWidth * 10, mazeHeight * 10)
        context.fillStyle = document.getElementById('txtPassageColor').value

        for (y = 0; y < mazeHeight; y++)
                map[y] = new Array(mazeWidth)
                
        for (y = 0; y < mazeHeight; y++)
                for (x = 0; x < mazeWidth; x++)
                        map[y][x] = 'wall'

        startPoint = new Point(1, 1)
                        
        context.fillRect(startPoint.x * 10, startPoint.y * 10, 10, 10)
        currentPoint = new Point(startPoint.x, startPoint.y)
        map[currentPoint.x][currentPoint.y] = 'passage'
        myStack.push(new Point(currentPoint.x, currentPoint.y))
        solution.push(new Point(currentPoint.x, currentPoint.y))

        drawSection()
        
/*      var myImage = myCanvas.toDataURL("image/png");
        document.write('<img src="' + myImage + '"/>');*/

}
function ToggleOptions() {
	if (document.getElementById('divOptions').style.display == 'none') {
		document.getElementById('divOptions').style.display = 'inherit'
	} else {
		document.getElementById('divOptions').style.display = 'none'
	}
}
function toggleEntrance() {
	canvas = document.getElementById('myCanvas')
	context = canvas.getContext('2d')
	mazeWidth = document.getElementById('txtWidth').value
	mazeHeight = document.getElementById('txtHeight').value
    //context.fillStyle = document.getElementById('txtWallColor').value
	context.fillStyle = document.getElementById('txtPassageColor').value
	context.fillRect(10, 0, 10, 10)
	context.fillRect(mazeWidth * 10 - 20, mazeHeight * 10 - 10, 10, 10)
}
</script>